package FrameWork.Event;

import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * EventManager的配置类
 */
@Component
public class TriggerManagerConfigure implements ApplicationContextAware {

    private Logger logger = Logger.getLogger(TriggerManagerConfigure.class);
    private ApplicationContext context;

    private TriggerManagerConfigure(){}

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
        init();
    }

    /**
     * 注册Event和EventHandler，在Spring容器初始化的时候调用
     */
    private void init() {
        //获得所有触发器实例
        Map<String, Trigger> eventMap = context.getBeansOfType(Trigger.class);
        //获得所有EventHandler实例
        Map<String, EventHandler> eventHandlers = context.getBeansOfType(EventHandler.class);
        //EventHandler类型->List<EventHandler>,一个类可以是继承多个接口
        Map<Class<? extends EventHandler>, List<EventHandler>> eventHandlerMap = getEventMap(eventHandlers.values());
        //对每一个触发器进行注册对应其泛型的EventHandler
        for (Trigger trigger : eventMap.values()) {
            //向TriggerManager注册事件
            TriggerManager.registerTrigger(trigger);
            //Trigger的具体类型
            Class<? extends Trigger> clazz = trigger.getClass();
            //Trigger的EventHandler的类型
            Class<? extends EventHandler> handlerType = TriggerReflectUtil.getEventHandlerType(clazz);
            if (eventHandlerMap.containsKey(handlerType)){
                for (EventHandler handler : eventHandlerMap.get(handlerType)) {
                    TriggerManager.safeRegisterEventHandler(clazz, handler);
                }
            }else{
                logger.info(trigger.getClass().getName()+"没有对应事件处理器"+handlerType.getName()+"的实现");
            }
        }
    }

    private Map<Class<? extends EventHandler>, List<EventHandler>> getEventMap(final Collection<EventHandler> handlers) {
        Map<Class<? extends EventHandler>,List<EventHandler>> handlerMap = new HashMap<>();
        for (EventHandler handler:handlers){
            //获取该handler的所有接口
            Class[] handlerItf = handler.getClass().getInterfaces();
            for (Class itf:handlerItf){
                if (EventHandler.class.isAssignableFrom(itf)){
                    if (!handlerMap.containsKey(itf)){
                        handlerMap.put(itf,new LinkedList<EventHandler>());
                    }
                    handlerMap.get(itf).add(handler);
                }
            }
        }
        return handlerMap;
    }

}
